package com.api.service.impl;

import java.time.LocalDateTime;
import java.util.Objects;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.alibaba.fastjson.JSONObject;
import com.api.common.Common;
import com.api.common.reqres.Request;
import com.api.common.reqres.Response;
import com.api.component.CacheComponent;
import com.api.component.HttpAPIComponent;
import com.api.component.JwtComponent;
import com.api.component.MD5UtilComponent;
import com.api.component.RequestComponent;
import com.api.component.ResponseComponent;
import com.api.mapper.FrontUserMapper;
import com.api.model.entity.FrontUser;
import com.api.model.request.FrontLoginRequest;
import com.api.model.request.FrontUserUpdateRequest;
import com.api.model.request.NullRequest;
import com.api.model.request.OpenidRequest;
import com.api.model.request.RegisteredRequest;
import com.api.model.request.SmsCodeRequest;
import com.api.model.response.FrontLoginResponse;
import com.api.model.response.NullResponse;
import com.api.model.response.OpenidResponse;
import com.api.model.response.RegisteredResponse;
import com.api.service.FrontUserService;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author cfp
 * @since 2019-10-14
 */
@Slf4j
@Service
public class FrontUserServiceImpl extends ServiceImpl<FrontUserMapper, FrontUser> implements FrontUserService {
	@Autowired
	private RequestComponent requestComponent;
	@Autowired
	private ResponseComponent responseComponent;
	@Autowired
	private FrontUserMapper frontUserMapper;
	@Autowired
	private CacheComponent cacheComponent;
	@Autowired
	private JwtComponent jwtComponent;
	@Autowired
	private HttpAPIComponent httpAPIComponent;
	@Autowired
	private MD5UtilComponent md5UtilComponent;

	@Override
	public Response<RegisteredResponse> registered(Request<RegisteredRequest> request) {
		// TODO Auto-generated method stub
		requestComponent.checkBody(request.getBody(), RegisteredRequest.class);
		RegisteredRequest registeredRequest = request.getBody();
		// 验证码验证
		String smsCodeCache = cacheComponent.getCacheValue(registeredRequest.getMobile());
		if (StringUtils.isNotBlank(smsCodeCache)) {
			if (!StringUtils.equals(smsCodeCache, registeredRequest.getSmsCode())) {
				return responseComponent.toError("验证码不正确,请重新输入!");
			}
		} else {
			return responseComponent.toError("请先获取验证码!");
		}
		// 判断是否手机号存在
		LambdaQueryWrapper<FrontUser> queryWrapper = new LambdaQueryWrapper<FrontUser>();
		queryWrapper.eq(FrontUser::getMobile, registeredRequest.getMobile());
		int count = frontUserMapper.selectCount(queryWrapper);
		if (count > 0) {
			return responseComponent.toError("手机号已注册!");
		}
		// 录入数据库
		FrontUser entity = new FrontUser();
		entity.setName(registeredRequest.getName());
		entity.setMobile(registeredRequest.getMobile());
		entity.setCampus(registeredRequest.getCampus());
		entity.setArea(registeredRequest.getArea());
		entity.setLocation(registeredRequest.getLocation());
		entity.setCreatetime(LocalDateTime.now());
		entity.setIntegral(0l);
		entity.setCreateuser(Common.SYSTEM);
		frontUserMapper.insert(entity);
		// 返回用户主键和token值
		FrontUser frontUser = frontUserMapper.selectOne(queryWrapper);
		String userid = frontUser.getOid() + "";
		RegisteredResponse response = new RegisteredResponse();
		response.setUserid(userid);
		String token = jwtComponent.createToken(userid).getToken();
		response.setToken(token);
		return responseComponent.toSuccess(response);
	}

	@Override
	public Response<NullResponse> smsCode(Request<SmsCodeRequest> request) {
		// TODO Auto-generated method stub
		requestComponent.checkBody(request.getBody(), SmsCodeRequest.class);
		SmsCodeRequest smsCodeRequest = request.getBody();
		String smsCode = (int) ((Math.random() * 9 + 1) * 100000) + "";
		log.info("手机号:" + smsCodeRequest.getMobile() + "验证码：" + smsCode);
		cacheComponent.setCacheSmsCode(smsCodeRequest.getMobile(), smsCode);
		return responseComponent.toSuccess(null);
	}

	@Override
	public Response<FrontLoginResponse> frontLogin(Request<FrontLoginRequest> request) {
		// TODO Auto-generated method stub
		requestComponent.checkBody(request.getBody(), FrontLoginRequest.class);
		FrontLoginRequest frontLoginRequest = request.getBody();
		// 验证码验证
		String smsCodeCache = cacheComponent.getCacheValue(frontLoginRequest.getMobile());
		if (StringUtils.isNotBlank(smsCodeCache)) {
			if (!StringUtils.equals(smsCodeCache, frontLoginRequest.getSmsCode())) {
				return responseComponent.toError("验证码不正确!");
			}
		} else {
			return responseComponent.toError("请先获取验证码!");
		}
		// 判断是否手机号存在
		LambdaQueryWrapper<FrontUser> queryWrapper = new LambdaQueryWrapper<FrontUser>();
		queryWrapper.eq(FrontUser::getMobile, frontLoginRequest.getMobile());
		FrontUser frontUser = frontUserMapper.selectOne(queryWrapper);
		if (Objects.isNull(frontUser)) {
			return responseComponent.toError("手机号未注册!");
		}
		String userid = frontUser.getOid() + "";
		FrontLoginResponse response = new FrontLoginResponse();
		response.setUserid(frontUser.getOid() + "");
		String key = String.format(Common.USER_TOKEN_TEMPLATE, userid, Common.LOGIN_SOURCE_FRONT);
		String token = jwtComponent.createToken(key).getToken();
		response.setToken(token);
		// 放到缓存
		String cacheKey = md5UtilComponent.md5(Common.TOKEN + userid + Common.LOGIN_SOURCE_FRONT).toUpperCase();
		cacheComponent.setCacheToken(cacheKey, token);
		return responseComponent.toSuccess(response);
	}

	@Override
	public Response<NullResponse> frontUser(Request<NullRequest> request) {
		// TODO Auto-generated method stub
		String userid = request.getHead().getUserid();
		LambdaQueryWrapper<FrontUser> queryWrapper = new LambdaQueryWrapper<FrontUser>();
		queryWrapper.eq(FrontUser::getOid, Long.valueOf(userid));
		FrontUser frontUser = frontUserMapper.selectOne(queryWrapper);
		return responseComponent.toSuccess(frontUser);
	}

	@Override
	public Response<NullResponse> frontUserUpdate(Request<FrontUserUpdateRequest> request) {
		// TODO Auto-generated method stub
		FrontUserUpdateRequest frontUserUpdateRequest = request.getBody();
		requestComponent.checkBody(frontUserUpdateRequest, FrontUserUpdateRequest.class);
		String userid = request.getHead().getUserid();
		FrontUser entity = new FrontUser();
		BeanUtils.copyProperties(frontUserUpdateRequest, entity);
//		frontUserMapper.updateById(entity);
		LambdaUpdateWrapper<FrontUser> updateWrapper = new LambdaUpdateWrapper<FrontUser>();
		updateWrapper.eq(FrontUser::getOid, Long.valueOf(userid));
		frontUserMapper.update(entity, updateWrapper);
		return responseComponent.toSuccess(null);
	}

	@Override
	public Response<OpenidResponse> openid(Request<OpenidRequest> request) {
		// TODO Auto-generated method stub
		requestComponent.checkBody(request.getBody(), OpenidRequest.class);

		OpenidRequest openidRequest = request.getBody();
		StringBuffer url = new StringBuffer();
		url.append("https://api.weixin.qq.com/sns/jscode2session?");
		url.append("appid=" + openidRequest.getAppid());
		url.append("&secret=" + openidRequest.getSecret());
		url.append("&js_code=" + openidRequest.getJscode());
		url.append("&grant_type=authorization_code");
		log.info("请求:" + url);
		String responseJson = null;
		try {
			responseJson = httpAPIComponent.doGet(url.toString());
		} catch (Exception e) {
			// TODO: handle exception
			e.printStackTrace();
			return responseComponent.toError("获取openid失败");
		}
		log.info("返回参数:" + responseJson);
		JSONObject jsonObj = JSONObject.parseObject(responseJson);
		if (jsonObj.containsKey("errcode")) {
			if ("40029".equals(jsonObj.getString("errcode"))) {
				return responseComponent.toError("code无效");
			}
			if ("45011".equals(jsonObj.getString("errcode"))) {
				return responseComponent.toError("频率限制");
			}
			if ("-1".equals(jsonObj.getString("errcode"))) {
				return responseComponent.toError("系统繁忙");
			}
			if ("40163".equals(jsonObj.getString("errcode"))) {
				return responseComponent.toError("code已被其他地方使用");
			}

			return responseComponent.toError(jsonObj.getString("errmsg"));
		}
		String openid = jsonObj.getString("openid");
		OpenidResponse openidResponse = new OpenidResponse();
		openidResponse.setOpenid(openid);
		openidResponse.setSessionKey(jsonObj.getString("session_key"));
		return responseComponent.toSuccess(openidResponse);
	}

}
